/*
 * Created by SharpDevelop.
 * User: David
 * Date: 2006-12-25
 * Time: 01:37
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Windows.Forms;

using Labb4.Pooman.Cards;
using Labb4.Pooman.Players;
using Labb4.Pooman.Game;

namespace Labb4.Rules
{
	/// <summary>
	/// Description of SetOfRulesPhase2.
	/// </summary>
	public class SetOfRulesPhase2 : SetOfRules
	{
		#region constructors
		
		/// <summary>
		/// Constructor, does nothing (neither does base, do I have to declare them then?)
		/// </summary>
		public SetOfRulesPhase2() :
			base()
		{
		}
		
		#endregion
		
		#region overrides
		
		/// <summary>
		/// Checks what cards are playable. In this phase, if no cards have yet been played,
		/// all cards are playable. However, if there are allready cards on the table, only cards
		/// topping the highest card on the table are playable, the trump accounted for.
		/// 
		/// If cards are allready selected, only cards that are directly suited connected to this card
		/// are selectable. That's a maximum of 2 at a time.
		/// </summary>
		/// <param name="cards">The cards to check</param>
		/// <param name="round">Reference to the currently played round</param>
		/// <param name="trump">Reference to the current trump</param>
		/// <returns>The playable cards</returns>
		public override CardPile PerformCheckForPlayability(CardPile cards, Round round, Trump trump)
		{
			if(round == null)
			{
				MessageBox.Show("Oh no! Round round is null in SetOfRulesPhase2..");
			}
			
			if(trump == null)
			{
				MessageBox.Show("Oh no! Trumph trumph is null in SetOfRulesPhase2..");
			}
			
			CardPile playable = new CardPile();
			Card highestCard = round.GetHighestCardInPlay(trump);
			
			bool selected = false;
			Card.Suit chainedSuit = 0;
			
			foreach(Card it in cards)
			{
				if(it.Selected)
				{
					if(!selected)
					{
						playable.Add(it);
						selected = true;
						chainedSuit = it.SuitOfCard;
					}
				}
			}
			
			if(selected) //at least one card is selected, only cards connected in straight to the selected cards are playable
			{
				bool foundStartOfChain = false;
				bool foundBrokenChain = false;
				Card lastCard = null;
				
				foreach(Card it in cards)
				{
					if(!foundStartOfChain)
					{
						if(it.Selected)
						{
							foundStartOfChain = true;
							
							if(lastCard != null)
							{
								if(lastCard.SuitOfCard == it.SuitOfCard)
								{
									if((lastCard.ValueOfCard + 1) == it.ValueOfCard)
									{
										playable.Add(lastCard);
									}
								}
							}
						}
					}
					else
					{
						if(!foundBrokenChain)
						{
							if(it.Selected)
							{
								playable.Add(it);
							}
							else
							{
								if(it.SuitOfCard == chainedSuit)
								{
									if((lastCard.ValueOfCard + 1) == it.ValueOfCard)
									{
										playable.Add(it);
									}
								}
								
								foundBrokenChain = true;
							}
						}
						else
						{
							if(it.Selected)
							{
								it.SelectCard(false);
							}
						}
					}
					
					lastCard = it;
				}
			}
			else //no cards are selected, so all cards higher than the [highest card played so far] are selectable
			{
				foreach(Card it in cards)
				{
					if(highestCard != null)
					{
						if(highestCard.SuitOfCard == trump.TrumpSuit)
						{
							if((it.SuitOfCard == trump.TrumpSuit) && (it.ValueOfCard > highestCard.ValueOfCard)) //and here we find out if a card is higher than the highest played
							{
								playable.Add(it);
							}
						}
						else
						{
							if((it.SuitOfCard == trump.TrumpSuit) ||
							  ((it.SuitOfCard == highestCard.SuitOfCard) && (it.ValueOfCard > highestCard.ValueOfCard)))
							{
								playable.Add(it);
							}
						}
					}
					else //appearantly no cards have been played yet this stick, so all cards are playable..
					{
						playable.Add(it);
					}
				}
			}
			
			return playable;
		}
		
		#endregion
	}
}
